package io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;

public class SplitFile {
	
	private String filePath;
	
	private String fileName;
	
	private long fileLength;
	
	private long blockSize;
	
	private int size;
	
	private ArrayList<String> blockPath;
	
	public SplitFile(){
		this.blockPath = new ArrayList<String>();
	}
	
	public SplitFile(String filePath){
		this(filePath,1024);
	}
	
	public SplitFile(String filePath,long blockSize){
		this();
		this.filePath = filePath;
		this.blockSize = blockSize;
	}
	
	/*
	 * 初始化操作，计算块数，每块名称，大小
	 */
	private void init(){
		File src = null;
		if(null == filePath || ("").equals(filePath)){
			return;
		}
		src = new File(filePath);
		if(!src.exists() || src.isDirectory()){
			return;
		}
		
		this.fileName = src.getName();
		
		//文件实际大小
		this.fileLength = src.length();
		if(this.blockSize >= fileLength){
			this.blockSize = fileLength;
		}
		
		this.size = (int) Math.ceil(fileLength*1.0/this.blockSize);
		
	}
	
	private void initBlockPath(String destPath){
		for(int i = 0; i < size; i++){
			blockPath.add(destPath + "/" + this.fileName+i);
		}
	}
	
	/*
	 * 文件存放的目录
	 */
	public void split(String destPath){
		initBlockPath(destPath);
		long actualBlockSize = this.blockSize;
		
		for(int i = 0; i < size; i++){
			if(i == size - 1){
				actualBlockSize = this.fileLength - (i*this.blockSize);
			}
			splitDetail(i,i*this.blockSize,actualBlockSize);
		}
	}
	
	private void splitDetail(int blockNum,long beginLoc,long actualBlockSize ){
		File src = new File(this.filePath);
		File dest = new File(this.blockPath.get(blockNum));
		RandomAccessFile ra = null;
		BufferedOutputStream bo = null;
		try {
			 ra = new RandomAccessFile(src,"r");
			 bo = new BufferedOutputStream(new FileOutputStream(dest));
			 ra.seek(beginLoc);
			 byte[] flush = new byte[1024];
			 long len = 0;
			 long readLen = 0;
			 while(-1 != (len = ra.read(flush))){
				 readLen += len;
				 if(readLen > actualBlockSize){
					 len = actualBlockSize - (readLen - len);
					 bo.write(flush, 0, (int) len);
					 break;
				 }
				 bo.write(flush, 0, (int) len);
			 }
			 bo.flush();
			 
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(null != bo){
				try {
					bo.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(null != ra){
				try {
					ra.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	/*
	 * 文件的合并
	 */
	public void merge(String destPath){
		File dest = new File(destPath);
		BufferedInputStream bis = null;
		BufferedOutputStream bo = null;
		try {
			//true表示追加
			bo = new BufferedOutputStream(new FileOutputStream(dest,true));
			for(int i = 0; i < blockSize; i++){
			    bis = new BufferedInputStream(new FileInputStream(new File(this.blockPath.get(i))));
			    byte[] flush = new byte[1024];
				int len = 0;
				while(-1 != (len = bis.read(flush))){
				    bo.write(flush, 0, len);
				}
				bo.flush();
				if(null != bis){
					bis.close();
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(null != bo){
				try {
					bo.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
	}

	public static void main(String[] args) {
        
		
		
	}

}
